package logic

import (
	"context"
	"encoding/json"
	"fmt"

	"dfx_cmdb/cmdb-account-management-rpc/internal/svc"
	cmdb_account_management_rpc "dfx_cmdb/cmdb-account-management-rpc/types/cmdb-account-management-rpc"
	cmdbaccountmanagement "dfx_cmdb/models/cmdb-account-management"

	"github.com/zeromicro/go-zero/core/logx"
	"gorm.io/datatypes"
	"gorm.io/gorm"
)

type InsertAccountInfoLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewInsertAccountInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *InsertAccountInfoLogic {
	return &InsertAccountInfoLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *InsertAccountInfoLogic) InsertAccountInfo(in *cmdb_account_management_rpc.InsertAccountInfoRequest) (*cmdb_account_management_rpc.PublicResponse, error) {
	if len(in.AccountInfo) == 0 {
		logx.Error("账号信息不能为空")
		return &cmdb_account_management_rpc.PublicResponse{
			Message: "账号信息不能为空",
		}, fmt.Errorf("账号信息不能为空")
	}

	// 批量检查平台名称是否已存在
	platformNames := make([]string, 0, len(in.AccountInfo))
	for _, v := range in.AccountInfo {
		if v.PlatformName == "" {
			logx.Errorf("平台名称不能为空")
			return &cmdb_account_management_rpc.PublicResponse{
				Message: "平台名称不能为空",
			}, fmt.Errorf("平台名称不能为空")
		}
		platformNames = append(platformNames, v.PlatformName)
	}

	// 一次性查询所有可能重复的平台
	var existingAccounts []cmdbaccountmanagement.AccountManagement
	if err := l.svcCtx.PDB.WithContext(l.ctx).
		Where("platform_name IN ?", platformNames).
		Find(&existingAccounts).Error; err != nil {
		logx.Errorf("查询已存在平台失败: %v", err)
		return &cmdb_account_management_rpc.PublicResponse{
			Message: fmt.Sprintf("查询已存在平台失败: %v", err),
		}, err
	}

	// 构建已存在平台的 map
	existingMap := make(map[string]bool)
	for _, acc := range existingAccounts {
		existingMap[acc.PlatformName] = true
	}

	// 检查是否有重复并构建插入数据
	accInfos := make([]*cmdbaccountmanagement.AccountManagement, 0, len(in.AccountInfo))
	duplicates := make([]string, 0)

	for _, v := range in.AccountInfo {
		if existingMap[v.PlatformName] {
			duplicates = append(duplicates, v.PlatformName)
			continue
		}

		// 将 map[string]string 转换为 JSON
		otherInfoJSON := datatypes.JSON("{}")
		if len(v.OtherInfo) > 0 {
			if jsonBytes, err := json.Marshal(v.OtherInfo); err == nil {
				otherInfoJSON = datatypes.JSON(jsonBytes)
			}
		}

		accInfos = append(accInfos, &cmdbaccountmanagement.AccountManagement{
			Type:         v.Type,
			Platform:     v.Platform,
			PlatformName: v.PlatformName,
			Account:      v.Account,
			Password:     v.Password,
			Token:        v.Token,
			Accesskey:    v.Accesskey,
			Accesssecret: v.Accesssecret,
			Comment:      v.Comment,
			OtherInfo:    otherInfoJSON,
		})
	}

	// 如果有重复的平台
	if len(duplicates) > 0 {
		logx.Errorf("以下平台已存在: %v", duplicates)
		return &cmdb_account_management_rpc.PublicResponse{
			Message: fmt.Sprintf("以下平台已存在: %v", duplicates),
		}, fmt.Errorf("以下平台已存在: %v", duplicates)
	}

	// 如果没有需要插入的数据
	if len(accInfos) == 0 {
		logx.Info("没有需要插入的数据")
		return &cmdb_account_management_rpc.PublicResponse{
			Message: "没有需要插入的数据",
		}, nil
	}

	// 使用事务批量插入
	err := l.svcCtx.PDB.WithContext(l.ctx).Transaction(func(tx *gorm.DB) error {
		if err := tx.Create(&accInfos).Error; err != nil {
			return err
		}
		return nil
	})

	if err != nil {
		logx.Errorf("插入账号信息失败: %v", err)
		return &cmdb_account_management_rpc.PublicResponse{
			Message: fmt.Sprintf("插入账号信息失败: %v", err),
		}, err
	}

	logx.Infof("成功插入 %d 条账号信息", len(accInfos))
	return &cmdb_account_management_rpc.PublicResponse{
		Message: fmt.Sprintf("成功插入 %d 条账号信息", len(accInfos)),
	}, nil
}
